﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
using NHibernate;
using Journal.Domain;
using Journal.Persistence;

namespace Journal.Helpers.Test
{
    [TestFixture]
    class CalendarRepository_Fixture
    {
        private ISessionFactory _sessionFactory;
        private Configuration _configuration;

        [TestFixtureSetUp]
        public void TestFixtureSetUp()
        {
            _configuration = new Configuration();
            _configuration.Configure();
            _configuration.AddAssembly(typeof(Calendar).Assembly);
            _sessionFactory = _configuration.BuildSessionFactory();
        }

        [SetUp]
        public void SetupContext()
        {
            new SchemaExport(_configuration).Execute(true, true, false);
            CreateInitialData();
        }

        private readonly Calendar[] _calendars = new[]
        {
            new Calendar {Name = "Personal", Description = "Personal calendar"},
            new Calendar {Name = "Default", Description = "Default calendar"},
            new Calendar {Name = "Work", Description = "Calendar for Work"},
        };

        private void CreateInitialData()
        {
            using (ISession session = _sessionFactory.OpenSession())
            using (ITransaction transaction = session.BeginTransaction())
            {
                foreach (var calendar in _calendars)
                {
                    session.Save(calendar);
                }
                transaction.Commit();
            }
        }

        [Test]
        public void Can_add_new_calendar()
        {
            var calendar = new Calendar { Name = "default", Description = "my default calendar" };
            ICalendarPersistenceManager repository = new CalendarPersistenceManager();
            repository.Add(calendar);

            // use session to try to load the product
            using (ISession session = _sessionFactory.OpenSession())
            {
                var fromDb = session.Get<Calendar>(calendar.Id);
                // Test that the calendar was successfully inserted
                Assert.IsNotNull(fromDb);
                Assert.AreNotSame(calendar, fromDb);
                Assert.AreEqual(calendar.Name, fromDb.Name);
                Assert.AreEqual(calendar.Description, fromDb.Description);
            }
        }

        [Test]
        public void Can_update_existing_calendar()
        {
            var calendar = _calendars[0];
            calendar.Name = "My Personal";
            ICalendarPersistenceManager repository = new CalendarPersistenceManager();
            repository.Update(calendar);

            // use session to try to load the product
            using (ISession session = _sessionFactory.OpenSession())
            {
                var fromDb = session.Get<Calendar>(calendar.Id);
                Assert.AreEqual(calendar.Name, fromDb.Name);
            }
        }

        [Test]
        public void Can_remove_existing_calendar()
        {
            var product = _calendars[0];
            ICalendarPersistenceManager repository = new CalendarPersistenceManager();
            repository.Delete(product);

            using (ISession session = _sessionFactory.OpenSession())
            {
                var fromDb = session.Get<Calendar>(product.Id);
                Assert.IsNull(fromDb);
            }
        }

        [Test]
        public void Can_get_existing_product_by_id()
        {
            ICalendarPersistenceManager repository = new CalendarPersistenceManager();
            var fromDb = repository.GetById(_calendars[1].Id);
            Assert.IsNotNull(fromDb);
            Assert.AreNotSame(_calendars[1], fromDb);
            Assert.AreEqual(_calendars[1].Name, fromDb.Name);
        }

        [Test]
        public void Can_get_existing_product_by_name()
        {
            ICalendarPersistenceManager repository = new CalendarPersistenceManager();
            var fromDb = repository.GetByName(_calendars[1].Name);

            Assert.IsNotNull(fromDb);
            Assert.AreNotSame(_calendars[1], fromDb);
            Assert.AreEqual(_calendars[1].Id, fromDb.Id);
        }

    }
}
